package nl.tudelft.jpacman.level;

import nl.tudelft.jpacman.board.Board;
import nl.tudelft.jpacman.board.BoardFactory;
import nl.tudelft.jpacman.board.Square;
import nl.tudelft.jpacman.npc.Ghost;
import java.util.ArrayList;
import java.util.List;

public abstract class MapParser {
    private final LevelFactory levelFactory;
    private final BoardFactory boardFactory;
    private final CollisionMap collisionMap;

    public MapParser(LevelFactory levelFactory, BoardFactory boardFactory) {
        this.levelFactory = levelFactory;
        this.boardFactory = boardFactory;
        this.collisionMap = new PlayerCollisions();
    }

    public Level parseMap(char[][] map) {
        List<Square> startPositions = new ArrayList<>();
        List<Ghost> ghosts = new ArrayList<>();
        Square[][] grid = createGrid(map);

        // 单次遍历处理所有逻辑（移除原createGrid中的幽灵处理）
        for (int x = 0; x < map.length; x++) {
            for (int y = 0; y < map[x].length; y++) {
                char c = map[x][y];
                Square square = grid[x][y];

                // 确保每个字符只处理一次
                switch (c) {
                    case 'P':
                        startPositions.add(square);
                        break;
                    case 'G':
                        addGhost(square, ghosts);
                        break;
                }
            }
        }
        return new Level(boardFactory.buildBoard(grid), ghosts, startPositions, collisionMap);
    }

    private Square[][] createGrid(char[][] map) {
        Square[][] grid = new Square[map.length][];
        for (int x = 0; x < map.length; x++) {
            grid[x] = new Square[map[x].length];
            for (int y = 0; y < map[x].length; y++) {
                // 仅处理地形，不涉及实体
                switch (map[x][y]) {
                    case '#':
                        grid[x][y] = boardFactory.createWall();
                        break;
                    default:
                        grid[x][y] = boardFactory.createGround();
                        break;
                }
            }
        }
        return grid;
    }

    private void addGhost(Square square, List<Ghost> ghosts) {
        Ghost ghost = levelFactory.createGhost();
        ghost.occupy(square);
        ghosts.add(ghost);
    }

    protected abstract void addSquare(Square[][] grid, List<Ghost> ghosts, List<Square> startPositions, int x, int y, char c);
}
